<?php
/*
* @package paymentMethod
* @copyright Copyright 2003-2010 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: gobaldbill.php 2010-12-01
*
* Gobaldbill Pay Plugin
* Date: June 1, 2015
* Description: Implementation of the Gobaldbill Pay Gateway Service API v1.2 in PHP for ZenCart.

Best Regards,
rolandwz@live.cn

********************************************/ 
 
/**
 * PayJunction Payment Module (QuickLink)
 * You must have SSL active on your server to be compliant with merchant TOS
 *
 */
class gobaldbill extends base {
  /**
   * $code determines the internal 'code' name used to designate "this" payment module
   *
   * @var string
   */
  var $code;
  /**
   * $title is the displayed name for this payment method
   *
   * @var string
   */
  var $title;
  /**
   * $description is a soft name for this payment method
   *
   * @var string
   */
  var $description;
  /**
   * $enabled determines whether this module shows or not... in catalog.
   *
   * @var boolean
   */
  var $enabled;
  /**
   * $delimiter determines what separates each field of returned data from PayJunction authorize.net emulator
   *
   * @var string (single char)
   */
  var $delimiter = ',';
  /**
   * $encapChar denotes what character is used to encapsulate the response fields
   *
   * @var string (single char)
   */
  var $encapChar = '*';
  /**
   * log file folder
   *
   * @var string
   */
  var $_logDir = '';
  /**
   * communication vars
   */
  var $authorize = '';
  var $commErrNo = 0;
  var $commError = '';
  
  var $payment_succeed = '';
  var $payment_message = '';
  /**
   * debug content var
   */
  var $reportable_submit_data = array();
  /**
   * Constructor
   *
   * @return gobaldbill
   */
  function gobaldbill() {
    global $order, $messageStack;
    $this->code = 'gobaldbill';
    
    $this->enabled = ((MODULE_PAYMENT_GOBALDBILL_STATUS == 'True') ? true : false); // Whether the module is installed or not
    
    if (IS_ADMIN_FLAG === true) {
      // Payment module title in Admin
      $this->title = MODULE_PAYMENT_GOBALDBILL_TEXT_ADMIN_TITLE;
    } else {
      $this->title = MODULE_PAYMENT_GOBALDBILL_TEXT_CATALOG_TITLE; // Payment module title in Catalog
    }
    
    $this->description = MODULE_PAYMENT_GOBALDBILL_TEXT_DESCRIPTION; // Descriptive Info about module in Admin
    $this->sort_order = MODULE_PAYMENT_GOBALDBILL_SORT_ORDER; // Sort Order of this payment option on the customer payment page
    $this->form_action_url = zen_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL', false); // Page to go to upon submitting page info
    $this->order_status = (int)DEFAULT_ORDERS_STATUS_ID;
    if ((int)MODULE_PAYMENT_GOBALDBILL_ORDER_STATUS_ID > 0) {
      $this->order_status = (int)MODULE_PAYMENT_GOBALDBILL_ORDER_STATUS_ID;
    }
    // Reset order status to pending if capture pending:
    if (MODULE_PAYMENT_GOBALDBILL_AUTHORIZATION_TYPE == 'Authorize') $this->order_status = 1;

    $this->_logDir = DIR_FS_SQL_CACHE;

    if (is_object($order)) $this->update_status();
  }
  /**
   * Check to see whether module is installed
   *
   * @return boolean
   */
  function check() {
    global $db;
    if (!isset($this->_check)) {
      $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_GOBALDBILL_STATUS'");
      $this->_check = $check_query->RecordCount();
    }
    return $this->_check;
  }
   
  /**
   * calculate zone matches and flag settings to determine whether this module should display to customers or not
   *
   */
  function update_status() {
    global $order, $db;
    if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_GOBALDBILL_ZONE > 0) ) {
      $check_flag = false;
      $check = $db->Execute("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_GOBALDBILL_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
      while (!$check->EOF) {
        if ($check->fields['zone_id'] < 1) {
          $check_flag = true;
          break;
        } elseif ($check->fields['zone_id'] == $order->billing['zone_id']) {
          $check_flag = true;
          break;
        }
        $check->MoveNext();
      }

      if ($check_flag == false) {
        $this->enabled = false;
      }
    }
  }
  
  /**
   * JS validation which does error-checking of data-entry if this module is selected for use
   * (Number, Owner, and CVV Lengths)
   *
   * @return string
   */
  function javascript_validation() {
    
    $js = '  if (payment_value == "' . $this->code . '") {' . "\n";
    $js .=  '    var cc_card_type = document.checkout_payment.gobaldbill_cc_card_type.value;' . "\n";
    $js .=  '    var cc_number = document.checkout_payment.gobaldbill_cc_number.value;' . "\n";

    if (MODULE_PAYMENT_GOBALDBILL_USE_CVV == 'True')  {
      $js .= '    var cc_cvv = document.checkout_payment.gobaldbill_cc_cvv.value;' . "\n";
    }
    $js .=  '    if (cc_card_type == "0") {' . "\n" .
    '      error_message = error_message + "' . MODULE_PAYMENT_GOBALDBILL_TEXT_JS_CC_CARD_TYPE . '";' . "\n" .
    '      error = 1;' . "\n" .
    '    }' . "\n" .
    '    if (cc_number == "" || cc_number.length < ' . CC_NUMBER_MIN_LENGTH . ') {' . "\n" .
    '      error_message = error_message + "' . MODULE_PAYMENT_GOBALDBILL_TEXT_JS_CC_NUMBER . '";' . "\n" .
    '      error = 1;' . "\n" .
    '    }' . "\n";


    if (MODULE_PAYMENT_GOBALDBILL_USE_CVV == 'True')  {
      $js .= '    if (cc_cvv == "" || cc_cvv.length < "3" || cc_cvv.length > "4") {' . "\n".
      '      error_message = error_message + "' . MODULE_PAYMENT_GOBALDBILL_TEXT_JS_CC_CVV . '";' . "\n" .
      '      error = 1;' . "\n" .
      '    }' . "\n" ;
    }


    $js .= '  }' . "\n";
    
    return $js;
  }
  /**
   * Display Credit Card Information Submission Fields on the Checkout Payment Page
   *
   * @return array
   */
  function selection() {
    global $order;

    for ($i=1; $i<13; $i++) {
      $expires_month[] = array('id' => sprintf('%02d', $i), 'text' => strftime('%B - (%m)',mktime(0,0,0,$i,1,2000)));
    }

    $today = getdate();
    for ($i=$today['year']; $i < $today['year']+10; $i++) {
      $expires_year[] = array('id' => strftime('%y',mktime(0,0,0,1,1,$i)), 'text' => strftime('%Y',mktime(0,0,0,1,1,$i)));
    }
    
    $onFocus = ' onfocus="methodSelect(\'pmt-' . $this->code . '\')"';

    $selection = array('id' => $this->code,
                       'module' => MODULE_PAYMENT_GOBALDBILL_PAYMENT_PAGE_MARK,
                       'fields' => array(
                                         array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_CREDIT_CARD_NUMBER,
                                               'field' => zen_draw_input_field('gobaldbill_cc_number', '', ' maxlength="16"' .'id="'.$this->code.'-cc-number"' . $onFocus . ' autocomplete="off"'),
                                               'tag' => $this->code.'-cc-number'),


                                         array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_CREDIT_CARD_EXPIRES,
                                               'field' => zen_draw_pull_down_menu('gobaldbill_cc_expires_month', $expires_month, strftime('%m'), 'id="'.$this->code.'-cc-expires-month"' . $onFocus) . '&nbsp;' . zen_draw_pull_down_menu('gobaldbill_cc_expires_year', $expires_year, '', 'id="'.$this->code.'-cc-expires-year"' . $onFocus),
                                               'tag' => $this->code.'-cc-expires-month')));
    if (MODULE_PAYMENT_GOBALDBILL_USE_CVV == 'True') {
      $selection['fields'][] = array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_CVV,
                                   'field' => zen_draw_password_field('gobaldbill_cc_cvv', '', 'size="4", maxlength="3"' . ' id="'.$this->code.'-cc-cvv"' . $onFocus . ' autocomplete="off"') . ' ' . '<a href="javascript:popupWindow(\'' . zen_href_link(FILENAME_POPUP_CVV_HELP) . '\')">' . MODULE_PAYMENT_GOBALDBILL_TEXT_POPUP_CVV_LINK . '</a>',
                                   'tag' => $this->code.'-cc-cvv');
    }
    return $selection;
  }
   
  /**
   * Evaluates the Credit Card Type for acceptance and the validity of the Credit Card Number & Expiration Date
   *
   */
  function pre_confirmation_check() {
    global $messageStack;

    include(DIR_WS_CLASSES . 'cc_validation.php');

    $cc_validation = new cc_validation();
    $result = $cc_validation->validate($_POST['gobaldbill_cc_number'], $_POST['gobaldbill_cc_expires_month'], $_POST['gobaldbill_cc_expires_year'], $_POST['gobaldbill_cc_cvv']);
    $error = '';
    switch ($result) {
      case -1:
      $error = sprintf(TEXT_CCVAL_ERROR_UNKNOWN_CARD, substr($cc_validation->cc_number, 0, 4));
      break;
      case -2:
      case -3:
      case -4:
      $error = TEXT_CCVAL_ERROR_INVALID_DATE;
      break;
      case false:
      $error = TEXT_CCVAL_ERROR_INVALID_NUMBER;
      break;
    }

	if(!isset($_POST['gobaldbill_cc_cvv'])||(isset($_POST['gobaldbill_cc_cvv'])&&empty($_POST['gobaldbill_cc_cvv'])))
	{
		$result=false;
		$error=MODULE_PAYMENT_GOBALDBILL_TEXT_JS_CC_CVV;
	}

    if ( ($result == false) || ($result < 1) ) {
      $messageStack->add_session('checkout_payment', $error . '<!-- ['.$this->code.'] -->', 'error');
      zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
    }

    $this->cc_card_number = $cc_validation->cc_number;
    $this->cc_expiry_month = $cc_validation->cc_expiry_month;
    $this->cc_expiry_year = $cc_validation->cc_expiry_year;
  }
  
  /**
   * Display Credit Card Information on the Checkout Confirmation Page
   *
   * @return array
   */
  function confirmation() {
    $confirmation = array('fields' => array(
                                            array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_CREDIT_CARD_NUMBER,
                                                  'field' => substr($this->cc_card_number, 0, 4) . str_repeat('X', (strlen($this->cc_card_number) - 8)) . substr($this->cc_card_number, -4)),
                                            array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_CREDIT_CARD_EXPIRES,
                                                  'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['gobaldbill_cc_expires_month'], 1, '20' . $_POST['gobaldbill_cc_expires_year']))) ));
    return $confirmation;
  }
  
  
    private function create_order() {
        global $db, $order, $order_totals;

        $order->info['order_status'] = MODULE_PAYMENT_GOBALDBILL_ORDER_STATUS_ID;
        if ($order->info['total'] == 0) {
            if (DEFAULT_ZERO_BALANCE_ORDERS_STATUS_ID == 0) {
                $order->info['order_status'] = DEFAULT_ORDERS_STATUS_ID;
            } else if ($_SESSION['payment'] != 'freecharger') {
                $order->info['order_status'] = DEFAULT_ZERO_BALANCE_ORDERS_STATUS_ID;
            }
        }

        if ($_SESSION['shipping'] == 'free_free') {
            $order->info['shipping_module_code'] = $_SESSION['shipping'];
        }

        $sql_data_array = array(
            'customers_id' => $_SESSION['customer_id'],
            'customers_name' => $order->customer['firstname'] . ' ' . $order->customer['lastname'],
            'customers_company' => $order->customer['company'],
            'customers_street_address' => $order->customer['street_address'],
            'customers_suburb' => $order->customer['suburb'],
            'customers_city' => $order->customer['city'],
            'customers_postcode' => $order->customer['postcode'],
            'customers_state' => $order->customer['state'],
            'customers_country' => $order->customer['country']['title'],
            'customers_telephone' => $order->customer['telephone'],
            'customers_email_address' => $order->customer['email_address'],
            'customers_address_format_id' => $order->customer['format_id'],
            'delivery_name' => $order->delivery['firstname'] . ' ' . $order->delivery['lastname'],
            'delivery_company' => $order->delivery['company'],
            'delivery_street_address' => $order->delivery['street_address'],
            'delivery_suburb' => $order->delivery['suburb'],
            'delivery_city' => $order->delivery['city'],
            'delivery_postcode' => $order->delivery['postcode'],
            'delivery_state' => $order->delivery['state'],
            'delivery_country' => $order->delivery['country']['title'],
            'delivery_address_format_id' => $order->delivery['format_id'],
            'billing_name' => $order->billing['firstname'] . ' ' . $order->billing['lastname'],
            'billing_company' => $order->billing['company'],
            'billing_street_address' => $order->billing['street_address'],
            'billing_suburb' => $order->billing['suburb'],
            'billing_city' => $order->billing['city'],
            'billing_postcode' => $order->billing['postcode'],
            'billing_state' => $order->billing['state'],
            'billing_country' => $order->billing['country']['title'],
            'billing_address_format_id' => $order->billing['format_id'],
            'payment_method' => 'Credit Card Payment', 
            'payment_module_code' => $this->code,
            'shipping_method' => $order->info['shipping_method'],
            'shipping_module_code' => (strpos($order->info['shipping_module_code'], '_') > 0 ? substr($order->info['shipping_module_code'], 0, strpos($order->info['shipping_module_code'], '_')) : $order->info['shipping_module_code']),
            'coupon_code' => $order->info['coupon_code'],
			'cc_type' =>'',
            'cc_owner' => $order->info['cc_owner'],
            'cc_number' => $order->info['cc_number'],
            'cc_expires' => $order->info['cc_expires'],
            'date_purchased' => 'now()',
            'orders_status' => $order->info['order_status'],
            'order_total' => $order->info['total'],
            'order_tax' => $order->info['tax'],
            'currency' => $order->info['currency'],
            'currency_value' => $order->info['currency_value'],
            'ip_address' => $_SESSION['customers_ip_address'] . ' - ' . $_SERVER['REMOTE_ADDR']
        );
        zen_db_perform(TABLE_ORDERS, $sql_data_array);
        $insert_id = $db->Insert_ID();
        $order->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ORDER_HEADER', array_merge(array('orders_id' => $insert_id, 'shipping_weight' => $_SESSION['cart']->weight), $sql_data_array));

        for ($i = 0, $n = sizeof($order_totals); $i < $n; $i++) {
            $sql_data_array = array(
                'orders_id' => $insert_id,
                'title' => $order_totals[$i]['title'],
                'text' => $order_totals[$i]['text'],
                'value' => (is_numeric($order_totals[$i]['value'])) ? $order_totals[$i]['value'] : '0',
                'class' => $order_totals[$i]['code'],
                'sort_order' => $order_totals[$i]['sort_order']
            );
            zen_db_perform(TABLE_ORDERS_TOTAL, $sql_data_array);
            $order->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ORDERTOTAL_LINE_ITEM', $sql_data_array);
        }

        $sql_data_array = array('orders_id' => $insert_id,
            'orders_status_id' => $order->info['order_status'],
            'date_added' => 'now()',
            'customer_notified' => 0,
            'comments' => $order->info['comments']
        );
        zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
        $order->notify('NOTIFY_ORDER_DURING_CREATE_ADDED_ORDER_COMMENT', $sql_data_array);

        $order->create_add_products($insert_id);

		 $_SESSION['order_number_created'] = $insert_id;
		 $order->send_order_email($insert_id, 2); 

        return $insert_id;
    }
	
  /**
   * Build the data and actions to process when the "Submit" button is pressed on the order-confirmation screen.
   * This sends the data to the payment gateway for processing.
   * (These are hidden fields on the checkout confirmation page)
   *
   * @return string
   */
  function process_button() {
    $process_button_string = zen_draw_hidden_field('cc_expires_month', $this->cc_expiry_month) .
                             zen_draw_hidden_field('cc_expires_year', $this->cc_expiry_year) .
                             zen_draw_hidden_field('cc_number', $this->cc_card_number);
					
    if (MODULE_PAYMENT_GOBALDBILL_USE_CVV == 'True') {
      $process_button_string .= zen_draw_hidden_field('cc_cvv', $_POST['gobaldbill_cc_cvv']);
    }
    $process_button_string .= zen_draw_hidden_field(zen_session_name(), zen_session_id());

    return $process_button_string;
  }
  
  /**
   * Store the CC info to the order and process any results that come back from the payment gateway
   *
   */
  function before_process() {
    global $response, $db, $order, $messageStack, $currencies;//=====================
    $order->info['cc_number']  = str_pad(substr($_POST['cc_number'], -4), strlen($_POST['cc_number']), "X", STR_PAD_LEFT);


    $order->info['cc_expires'] = '';  // $_POST['cc_expires'];
    $order->info['cc_cvv']     = '***'; //$_POST['cc_cvv'];
    $sessID = zen_session_id();

    // DATA PREPARATION SECTION
    unset($submit_data);  // Cleans out any previous data stored in the variable

    // Create a variable that holds the order time
    $order_time = date("F j, Y, g:i a");

    // Calculate the next expected order id (adapted from code written by Eric Stamper - 01/30/2004 Released under GPL)
    $order_id = $this->create_order();
    
    $PName = '';
    $PNumber = '';
    $PPrice = '';
    for ($i = 0; $i < sizeof($order->products); $i++) {
        $PName = $PName . $order->products[$i]["name"] . "#" . $order->products[$i]["model"] . ",";
        $PNumber = $PNumber . $order->products[$i]['qty'] . ",";
	   $PPrice =$PPrice .number_format( $order->products[$i]['final_price'] * $currencies->get_value($_SESSION['currency']), 2, '.', '') . ",";
    }
    
    $v_merNo = trim(MODULE_PAYMENT_GOBALDBILL_LOGIN);
	$v_amount = number_format($order->info['total']* $currencies->get_value($_SESSION['currency']), 2,'.', '');

    $v_ccy = $order->info['currency'];
    $v_MD5key = trim(MODULE_PAYMENT_GOBALDBILL_MD5HASH);
	$v_email = $order->customer['email_address'];

    $signMsgVal = $v_merNo . $order_id . $v_amount . $v_ccy . $v_MD5key . $v_email;
    $v_md5info = $this->calc_md5($signMsgVal);
	
	$returnURL =$_SERVER["HTTP_HOST"];
	if(!stristr($returnURL,'www.')){
		$returnURL = 'www.'.$returnURL;
	}

    // Populate an array that contains all of the data to be sent to PayJunction
    $submit_data = array(
                         'merNo' => $v_merNo,
						 'accessVersion'=>'1',
                         'orderNo' => $order_id,
                         'returnURL' => $returnURL,
                         'amount' => $v_amount,
                         'currency' => $v_ccy,
                         'productType' => '0',
                         'shopName' => 'zencart',
                         'goodsName' => $PName,
                         'goodsNumber' => $PNumber,
                         'goodsPrice' => $PPrice,
                         'billFirstName' => $order->billing['firstname'],
                         'billLastName' => $order->billing['lastname'],
                         'billAddress' => $order->billing['street_address'],
                         'billCity' => $order->billing['city'],
                         'billState' => $order->billing['state'],
                         'billCountry' => $order->billing['country']['iso_code_2'],
                         'billZipCode' => $order->billing['postcode'],
						 'bankName' =>'',
						 'bankAccountNumber' => $_POST['cc_number'],
                         'expireMonth' => $_POST['cc_expires_month'],
                         'expireYear' => $_POST['cc_expires_year'],
                         'cvv' => $_POST['cc_cvv'],
                         'payMethod' => '0',
                         'email' => $v_email,
						 'shipEmail' => $v_email,
                         'phone' => $order->customer['telephone'],
                         'shipFirstName' => $order->delivery['firstname'],
                         'shipLastName' => $order->delivery['lastname'],
                         'shipAddress' => $order->delivery['street_address'],
                         'shipCity' => $order->delivery['city'],
                         'shipState' => $order->delivery['state'],
                         'shipCountry' => $order->delivery['country']['iso_code_2'],
                         'shipZipCode' => $order->delivery['postcode'],
                         'remark' => '',
                         'acceptLanguage' => substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 30),
                         'userAgent' => substr($_SERVER['HTTP_USER_AGENT'], 0, 30),
                         'referer' => $returnURL,
                         'clientIp' => zen_get_ip_address(),
                         'language' => 'en',
                         'md5Info' => $v_md5info);
						 
				
    unset($response);
    $response = $this->_sendRequest($submit_data);
    $this->payment_succeed = $response['succeed'];
    $this->transaction_id = $response['tradeNo'];
    $this->payment_message = $response['errcode'];
    
    $v_retSignMsg = $v_MD5key . $v_merNo . $response['orderNo'] 
                      . $response['amount'] . $response['currency'] . $response['succeed'];
    $v_retSignMD5 = $this->calc_md5($v_retSignMsg);
    
    error_log($v_retSignMD5 . ' ' . $v_retSignMsg . "\n", 3, "logs/gobaldbill_log.log");
    
    $response_msg_to_customer = $response['errcode'] . ($this->commError == '' ? '' : ' Communications Error - Please notify webmaster.');
    if ($v_retSignMD5 == $response['md5info']) {      
		if($response['succeed'] == '1'){
			$status_id = MODULE_PAYMENT_GOBALDBILL_SUCCESS_ORDER_STATUS_ID;
			$db->Execute("update " . TABLE_ORDERS . "
						set orders_status = '" . zen_db_input($status_id) . "', last_modified = now() 
						where orders_id = '" . (int) $order_id . "'");

			$db->Execute("insert into " . TABLE_ORDERS_STATUS_HISTORY . "
					  (orders_id, orders_status_id, date_added, customer_notified, comments)
					  values ('" . zen_db_input($order_id) . "',
					  '" . zen_db_input($status_id) . "',
					  now(),
					  '0',
					  'transationID:".$this->transaction_id."')");
			zen_redirect(zen_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL', true, false));
		} else {
			$status_id = MODULE_PAYMENT_GOBALDBILL_FAIL_ORDER_STATUS_ID;
			$db->Execute("update " . TABLE_ORDERS . "
						set orders_status = '" . zen_db_input($status_id) . "', last_modified = now() 
						where orders_id = '" . (int) $order_id . "'");

			$db->Execute("insert into " . TABLE_ORDERS_STATUS_HISTORY . "
					  (orders_id, orders_status_id, date_added, customer_notified, comments)
					  values ('" . zen_db_input($order_id) . "',
					  '" . zen_db_input($status_id) . "',
					  now(),
					  '0',
					  '".$response_msg_to_customer."')");
			$messageStack->add_session('checkout_payment', $response_msg_to_customer . ' - ' . MODULE_PAYMENT_GOBALDBILL_TEXT_DECLINED_MESSAGE, 'error');
			zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
		}
	} else {
		$response_msg_to_customer .= ' Signature failure!';
		$messageStack->add_session('checkout_payment', $response_msg_to_customer . ' - ' . MODULE_PAYMENT_GOBALDBILL_TEXT_DECLINED_MESSAGE, 'error');
		zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
	}
  }
  
  /**
   * Post-process activities. Updates the order-status history data with the auth code from the transaction.
   *
   * @return boolean
   */
  function after_process() {
    global $insert_id, $db;
    $sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, customer_notified, date_added) values (:orderComments, :orderID, :orderStatus, -1, now() )";
    $sql = $db->bindVars($sql, ':orderComments', 'Credit Card payment.  SUCC: ' . $this->payment_succeed . '. TransID: ' . $this->transaction_id . '. Code: ' . $this->payment_message . '.', 'string');
    $sql = $db->bindVars($sql, ':orderID', $insert_id, 'integer');
    $sql = $db->bindVars($sql, ':orderStatus', $this->order_status, 'integer');
    $db->Execute($sql);
    return false;
  }
  
  /**
   * Used to display error message details
   *
   * @return array
   */
  function get_error() {
    $error = array('title' => MODULE_PAYMENT_GOBALDBILL_TEXT_ERROR,
                   'error' => stripslashes(urldecode($_GET['error'])));
    return $error;
  }  

  /**
   * Send communication request
   */
  function _sendRequest($submit_data) {
    
    $url = MODULE_PAYMENT_GOBALDBILL_URL;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch ,CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch ,CURLOPT_POSTFIELDS, http_build_query($submit_data));
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_SSLVERSION, '1');
    
    $retStr = curl_exec($ch);
    $commError = curl_error($ch);
    $commErrNo = curl_errno($ch);
    $commInfo = @curl_getinfo($ch);
    curl_close($ch);
    
    parse_str($retStr, $response);
    
    $response['md5info'] = str_replace(array("\n", "\t", "\r"), '', $response['md5info']);
    
    error_log($submit_data['orderNo'] . $submit_data['amount'] . MODULE_PAYMENT_GOBALDBILL_URL . "\n", 3, "logs/gobaldbill_log.log");
    error_log($commErrNo . ' : ' . $commError. "\n", 3, "logs/gobaldbill_log.log");
    error_log($retStr. "\n", 3, "logs/gobaldbill_log.log");
    
    return $response;
  }
  
  /**
   * Calculate validity of response
   */
  function calc_md5($input) {
    $keyMd5 = strtoupper(md5($input));
    return $keyMd5;
  }
  
   
  /**
   * Install the payment module and its configuration settings
   *
   */
  function install() {
    global $db, $messageStack;
    if (defined('MODULE_PAYMENT_GOBALDBILL_STATUS')) {
      $messageStack->add_session('Gobaldbill module already installed.', 'error');
      zen_redirect(zen_href_link(FILENAME_MODULES, 'set=payment&module=gobaldbill', 'NONSSL'));
      return 'failed';
    }
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Gobaldbill Module', 'MODULE_PAYMENT_GOBALDBILL_STATUS', 'True', 'Do you want to accept payments via Gobaldbill?', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('MerNo', 'MODULE_PAYMENT_GOBALDBILL_LOGIN', 'xxx', 'The Merchant NO', '6', '0', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Secret Key', 'MODULE_PAYMENT_GOBALDBILL_MD5HASH', 'xxx', 'Secret Key', '6', '0', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Pay Gateway', 'MODULE_PAYMENT_GOBALDBILL_URL', 'https://gpco.gobaldbill.com:8443/GPCO', 'Gobaldbill pay gateway url', '6', '0', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display', 'MODULE_PAYMENT_GOBALDBILL_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Request CVV Number', 'MODULE_PAYMENT_GOBALDBILL_USE_CVV', 'True', 'Do you want to ask the customer for the card\'s CVV number', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
    $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set New Order Status', 'MODULE_PAYMENT_GOBALDBILL_ORDER_STATUS_ID', '1', 'Set the status of new orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
	$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Success Order Status', 'MODULE_PAYMENT_GOBALDBILL_SUCCESS_ORDER_STATUS_ID', '2', 'Set the status of successful orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
	$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Failed Order Status', 'MODULE_PAYMENT_GOBALDBILL_FAIL_ORDER_STATUS_ID', '2', 'Set the status of failed orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
  }
  /**
   * Remove the module and all its settings
   *
   */
  function remove() {
    global $db;
    $db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key like 'MODULE_PAYMENT_GOBALDBILL_%'");
  }
  /**
   * Internal list of configuration keys used for configuration of the module
   *
   * @return array
   */
  function keys() {
    return array('MODULE_PAYMENT_GOBALDBILL_STATUS', 
                 'MODULE_PAYMENT_GOBALDBILL_LOGIN',
                 'MODULE_PAYMENT_GOBALDBILL_MD5HASH', 
                 'MODULE_PAYMENT_GOBALDBILL_URL', 
                 'MODULE_PAYMENT_GOBALDBILL_SORT_ORDER', 
                 'MODULE_PAYMENT_GOBALDBILL_USE_CVV', 
                 'MODULE_PAYMENT_GOBALDBILL_ORDER_STATUS_ID',
				 'MODULE_PAYMENT_GOBALDBILL_SUCCESS_ORDER_STATUS_ID',
				 'MODULE_PAYMENT_GOBALDBILL_FAIL_ORDER_STATUS_ID');
  }
}
